diff --git a/.changesets/breaking_nc_config_file.md b/.changesets/breaking_nc_config_file.md deleted file mode 100644 index 59a973fb..00000000 --- a/.changesets/breaking_nc_config_file.md +++ /dev/null @@ -1,41 +0,0 @@ -### Replace CLI flags with a configuration file - @nicholascioli PR #162 - -All command line arguments are now removed and replaced with equivalent configuration -options. The Apollo MCP server only accepts a single argument which is a path to a -configuration file. An empty file may be passed, as all options have sane defaults -that follow the previous argument defaults. - -Below is a valid configuration file with some options filled out: - -```yaml -custom_scalars: /path/to/custom/scalars -endpoint: http://127.0.0.1:4000 -graphos: - apollo_key: some.key - apollo_graph_ref: example@graph -headers: - X-Some-Header: example-value -introspection: - execute: - enabled: true - introspect: - enabled: false -log_level: info -operations: - source: local - paths: - - /path/to/operation.graphql - - /path/to/other/operation.graphql -overrides: - disable_type_description: false - disable_schema_description: false - enable_explorer: false - mutation_mode: all -schema: - source: local - path: /path/to/schema.graphql -transport: - type: streamable_http - address: 127.0.0.1 - port: 5000 -``` diff --git a/.changesets/feat_pubmodmatt_minify.md b/.changesets/feat_pubmodmatt_minify.md deleted file mode 100644 index c8e87a36..00000000 --- a/.changesets/feat_pubmodmatt_minify.md +++ /dev/null @@ -1,3 +0,0 @@ -### Minify introspect return value - @pubmodmatt PR #178 - -The `introspect` and `search` tools now have an option to minify results. Minified GraphQL SDL takes up less space in the context window. \ No newline at end of file diff --git a/.changesets/feat_pubmodmatt_search.md b/.changesets/feat_pubmodmatt_search.md deleted file mode 100644 index 75c86b2d..00000000 --- a/.changesets/feat_pubmodmatt_search.md +++ /dev/null @@ -1,3 +0,0 @@ -### Add search tool - @pubmodmatt PR #171 - -A new experimental `search` tool has been added that allows the AI model to specify a set of terms to search for in the GraphQL schema. The top types matching that search are returned, as well as enough information to enable creation of GraphQL operations involving those types. \ No newline at end of file diff --git a/.changesets/feat_validate_tool.md b/.changesets/feat_validate_tool.md deleted file mode 100644 index 3406b171..00000000 --- a/.changesets/feat_validate_tool.md +++ /dev/null @@ -1,3 +0,0 @@ -### feat: Validate tool for verifying graphql queries before executing them - @swcollard PR #203 - -The introspection options in the mcp server provide introspect, execute, and search tools. The LLM often tries to validate its queries by just executing them. This may not be desired (there might be side effects, for example). This feature adds a `validate` tool so the LLM can validate the operation without actually hitting the GraphQL endpoint. It first validates the syntax of the operation, and then checks it against the introspected schema for validation. \ No newline at end of file diff --git a/.github/workflows/release-bins.yml b/.github/workflows/release-bins.yml index 0716023b..3f808715 100644 --- a/.github/workflows/release-bins.yml +++ b/.github/workflows/release-bins.yml @@ -184,6 +184,13 @@ jobs: tar -C release/$RELEASE -cf - dist/ | gzip -9 > artifacts/apollo-mcp-server-$VERSION-$RENAMED.tar.gz done + # We only need to generate the config schema for a release once, so we do it + # on the linux host since it is the cheapest. + - name: Generate config schema + if: ${{ matrix.bundle == 'linux' }} + run: | + ./release/x86_64-unknown-linux-musl/dist/config-schema > artifacts/config.schema.json + - name: Upload release artifacts uses: softprops/action-gh-release@v2 with: diff --git a/.github/workflows/release-container.yml b/.github/workflows/release-container.yml index 23916a02..fdc752ce 100644 --- a/.github/workflows/release-container.yml +++ b/.github/workflows/release-container.yml @@ -98,6 +98,12 @@ jobs: docker manifest annotate $FQDN:latest $FQDN:$VERSION-amd64 --arch amd64 docker manifest annotate $FQDN:latest $FQDN:$VERSION-arm64 --arch arm64 - name: Push the multiarch manifests + shell: bash run: | docker manifest push $FQDN:$VERSION - docker manifest push $FQDN:latest + + # Only push the latest tag if this isn't a release candidate (ends with + # `rc.#`. + if [[ ! "$VERSION" =~ -rc\.[0-9]+$ ]]; then + docker manifest push $FQDN:latest + fi diff --git a/CHANGELOG.md b/CHANGELOG.md index 21391c89..6bacb7fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,78 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +# [0.6.0] - 2025-07-14 + +## ❗ BREAKING ❗ + +### Replace CLI flags with a configuration file - @nicholascioli PR #162 + +All command line arguments are now removed and replaced with equivalent configuration +options. The Apollo MCP server only accepts a single argument which is a path to a +configuration file. An empty file may be passed, as all options have sane defaults +that follow the previous argument defaults. + +All options can be overridden by environment variables. They are of the following +form: + +- Prefixed by `APOLLO_MCP_` +- Suffixed by the config equivalent path, with `__` marking nested options. + +E.g. The environment variable to change the config option `introspection.execute.enabled` +would be `APOLLO_MCP_INTROSPECTION__EXECUTE__ENABLED`. + +Below is a valid configuration file with some options filled out: + +```yaml +custom_scalars: /path/to/custom/scalars +endpoint: http://127.0.0.1:4000 +graphos: + apollo_key: some.key + apollo_graph_ref: example@graph +headers: + X-Some-Header: example-value +introspection: + execute: + enabled: true + introspect: + enabled: false +logging: + level: info +operations: + source: local + paths: + - /path/to/operation.graphql + - /path/to/other/operation.graphql +overrides: + disable_type_description: false + disable_schema_description: false + enable_explorer: false + mutation_mode: all +schema: + source: local + path: /path/to/schema.graphql +transport: + type: streamable_http + address: 127.0.0.1 + port: 5000 +``` + +## 🚀 Features + +### Validate tool for verifying graphql queries before executing them - @swcollard PR #203 + +The introspection options in the mcp server provide introspect, execute, and search tools. The LLM often tries to validate its queries by just executing them. This may not be desired (there might be side effects, for example). This feature adds a `validate` tool so the LLM can validate the operation without actually hitting the GraphQL endpoint. It first validates the syntax of the operation, and then checks it against the introspected schema for validation. + +### Minify introspect return value - @pubmodmatt PR #178 + +The `introspect` and `search` tools now have an option to minify results. Minified GraphQL SDL takes up less space in the context window. + +### Add search tool - @pubmodmatt PR #171 + +A new experimental `search` tool has been added that allows the AI model to specify a set of terms to search for in the GraphQL schema. The top types matching that search are returned, as well as enough information to enable creation of GraphQL operations involving those types. + + + # [0.5.2] - 2025-07-10 ## 🐛 Fixes diff --git a/Cargo.lock b/Cargo.lock index 8b27eab9..a5138ad1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -169,7 +169,7 @@ dependencies = [ [[package]] name = "apollo-mcp-registry" -version = "0.5.2" +version = "0.6.0" dependencies = [ "derivative", "derive_more 2.0.1", @@ -197,7 +197,7 @@ dependencies = [ [[package]] name = "apollo-mcp-server" -version = "0.5.2" +version = "0.6.0" dependencies = [ "anyhow", "apollo-compiler", @@ -240,7 +240,7 @@ dependencies = [ [[package]] name = "apollo-schema-index" -version = "0.5.2" +version = "0.6.0" dependencies = [ "apollo-compiler", "enumset", diff --git a/Cargo.toml b/Cargo.toml index 41b88077..39ecd3a2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ members = [ [workspace.package] authors = ["Apollo "] -version = "0.5.2" +version = "0.6.0" [workspace.dependencies] apollo-compiler = "1.27.0" diff --git a/crates/apollo-mcp-server/src/main.rs b/crates/apollo-mcp-server/src/main.rs index 90baafbe..e4a971a5 100644 --- a/crates/apollo-mcp-server/src/main.rs +++ b/crates/apollo-mcp-server/src/main.rs @@ -33,15 +33,16 @@ const STYLES: Styles = Styles::styled() )] struct Args { /// Path to the config file - config: PathBuf, + config: Option, } #[tokio::main] async fn main() -> anyhow::Result<()> { - let config: runtime::Config = { - let args = Args::parse(); - runtime::read_config(args.config)? - }; + let config: runtime::Config = Args::parse() + .config + .map(runtime::read_config) + .transpose()? + .unwrap_or_default(); let mut env_filter = EnvFilter::from_default_env().add_directive(config.logging.level.into()); @@ -134,7 +135,7 @@ async fn main() -> anyhow::Result<()> { .transport(config.transport) .schema_source(schema_source) .operation_source(operation_source) - .endpoint(config.endpoint) + .endpoint(config.endpoint.into_inner()) .maybe_explorer_graph_ref(explorer_graph_ref) .headers(config.headers) .execute_introspection(config.introspection.execute.enabled) diff --git a/crates/apollo-mcp-server/src/runtime.rs b/crates/apollo-mcp-server/src/runtime.rs index 1e9a9e99..85bfdbd8 100644 --- a/crates/apollo-mcp-server/src/runtime.rs +++ b/crates/apollo-mcp-server/src/runtime.rs @@ -4,6 +4,7 @@ //! related to runtime configuration. mod config; +mod endpoint; mod graphos; mod introspection; mod logging; diff --git a/crates/apollo-mcp-server/src/runtime/config.rs b/crates/apollo-mcp-server/src/runtime/config.rs index db68f034..ce064ae9 100644 --- a/crates/apollo-mcp-server/src/runtime/config.rs +++ b/crates/apollo-mcp-server/src/runtime/config.rs @@ -7,75 +7,48 @@ use serde::Deserialize; use url::Url; use super::{ - OperationSource, SchemaSource, graphos::GraphOSConfig, introspection::Introspection, - logging::Logging, overrides::Overrides, + OperationSource, SchemaSource, endpoint::Endpoint, graphos::GraphOSConfig, + introspection::Introspection, logging::Logging, overrides::Overrides, }; /// Configuration for the MCP server -#[derive(Debug, Deserialize, JsonSchema)] +#[derive(Debug, Default, Deserialize, JsonSchema)] +#[serde(default)] pub struct Config { /// Path to a custom scalar map pub custom_scalars: Option, /// The target GraphQL endpoint - #[serde(default = "defaults::endpoint")] - pub endpoint: Url, + #[schemars(schema_with = "Url::json_schema")] + pub endpoint: Endpoint, /// Apollo-specific credential overrides - #[serde(default)] pub graphos: GraphOSConfig, /// List of hard-coded headers to include in all GraphQL requests - #[serde(default, deserialize_with = "parsers::map_from_str")] + #[serde(deserialize_with = "parsers::map_from_str")] #[schemars(schema_with = "super::schemas::header_map")] pub headers: HeaderMap, /// Introspection configuration - #[serde(default)] pub introspection: Introspection, /// Logging configuration - #[serde(default)] pub logging: Logging, /// Operations - #[serde(default)] pub operations: OperationSource, /// Overrides for server behaviour - #[serde(default)] pub overrides: Overrides, /// The schema to load for operations - #[serde(default)] pub schema: SchemaSource, /// The type of server transport to use - #[serde(default)] pub transport: Transport, } -mod defaults { - use url::Url; - - pub(super) fn endpoint() -> Url { - // SAFETY: This should always parse correctly and is considered a breaking - // error otherwise. It is also explicitly tested in [test::default_endpoint_parses_correctly] - #[allow(clippy::unwrap_used)] - Url::parse("http://127.0.0.1:4000").unwrap() - } - - #[cfg(test)] - mod test { - use super::endpoint; - - #[test] - fn default_endpoint_parses_correctly() { - endpoint(); - } - } -} - mod parsers { use std::str::FromStr; diff --git a/crates/apollo-mcp-server/src/runtime/endpoint.rs b/crates/apollo-mcp-server/src/runtime/endpoint.rs new file mode 100644 index 00000000..bacb203b --- /dev/null +++ b/crates/apollo-mcp-server/src/runtime/endpoint.rs @@ -0,0 +1,67 @@ +//! Endpoint newtype +//! +//! This module defines a simple newtype around a Url for demarking a GraphQL +//! endpoint. This allows overlaying validation and default behaviour on top +//! of the wrapped URL. + +use std::ops::Deref; + +use serde::Deserialize; +use url::Url; + +/// A GraphQL endpoint +#[derive(Debug)] +pub struct Endpoint(Url); + +impl Endpoint { + /// Unwrap the endpoint into its inner URL + pub fn into_inner(self) -> Url { + self.0 + } +} + +impl Default for Endpoint { + fn default() -> Self { + Self(defaults::endpoint()) + } +} + +impl<'de> Deserialize<'de> for Endpoint { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + // This is a simple wrapper around URL, so we just use its deserializer + let url = Url::deserialize(deserializer)?; + Ok(Self(url)) + } +} + +impl Deref for Endpoint { + type Target = Url; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +mod defaults { + use url::Url; + + pub(super) fn endpoint() -> Url { + // SAFETY: This should always parse correctly and is considered a breaking + // error otherwise. It is also explicitly tested in [test::default_endpoint_parses_correctly] + #[allow(clippy::unwrap_used)] + Url::parse("http://127.0.0.1:4000").unwrap() + } + + #[cfg(test)] + mod test { + use super::endpoint; + + #[test] + fn default_endpoint_parses_correctly() { + endpoint(); + } + } +} diff --git a/docs/source/best-practices.mdx b/docs/source/best-practices.mdx index a1a7bbbf..ff25722d 100644 --- a/docs/source/best-practices.mdx +++ b/docs/source/best-practices.mdx @@ -24,7 +24,7 @@ In particular, we strongly recommend contract variants when using: If you register a persisted query with a specific client name instead of `null`, you must configure the MCP Server to send the necessary header indicating the client name to the router. -Use the `--header` option when running the MCP Server to pass the header to the router. The default name of the header expected by the router is `apollographql-client-name`. To use a different header name, configure `telemetry.apollo.client_name_header` in router YAML configuration. +Use the `headers` option when running the MCP Server to pass the header to the router. The default name of the header expected by the router is `apollographql-client-name`. To use a different header name, configure `telemetry.apollo.client_name_header` in router YAML configuration. ## Avoid token passthrough for authentication diff --git a/docs/source/command-reference.mdx b/docs/source/command-reference.mdx index 34daaa16..35f3a46c 100644 --- a/docs/source/command-reference.mdx +++ b/docs/source/command-reference.mdx @@ -26,14 +26,14 @@ To download a **specific version** of Apollo MCP Server (recommended for CI envi ```bash # Note the `v` prefixing the version number -docker image pull ghcr.io/apollographql/apollo-mcp-server:v0.5.2 +docker image pull ghcr.io/apollographql/apollo-mcp-server:v0.6.0 ``` To download a specific version of Apollo MCP Server that is a release candidate: ```bash # Note the `v` prefixing the version number and the `-rc` suffix -docker image pull ghcr.io/apollographql/apollo-mcp-server:v0.4.1-rc.1 +docker image pull ghcr.io/apollographql/apollo-mcp-server:v0.6.0-rc.1 ``` @@ -65,7 +65,7 @@ To install or upgrade to a **specific version** of Apollo MCP Server (recommende ```bash # Note the `v` prefixing the version number -curl -sSL https://mcp.apollo.dev/download/nix/v0.5.2| sh +curl -sSL https://mcp.apollo.dev/download/nix/v0.6.0 | sh ``` If your machine doesn't have the `curl` command, you can get the latest version from the [`curl` downloads page](https://curl.se/download.html). @@ -82,43 +82,134 @@ To install or upgrade to a **specific version** of Apollo MCP Server (recommende ```bash # Note the `v` prefixing the version number -iwr 'https://mcp.apollo.dev/download/win/v0.5.2' | iex +iwr 'https://mcp.apollo.dev/download/win/v0.6.0' | iex ``` ## Usage +Configure the Apollo MCP server with a configuration file. The path to this file is the only argument. + ```sh showLineNumbers=false -apollo-mcp-server [OPTIONS] --directory +apollo-mcp-server [OPTIONS] ``` -## Options - -| Option | Description | -| :---------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `-d, --directory ` | The working directory to use. Defaults the current working directory. | -| `-s, --schema ` | The path to the GraphQL API schema file. | -| `-c, --custom-scalars-config ` | The path to the GraphQL custom_scalars_config file. [Learn more](/apollo-mcp-server/guides/#custom-scalars-configuration). | -| `-e, --endpoint ` | The GraphQL endpoint the server will invoke.
[default: `http://127.0.0.1:4000`] | -| `--header ` | Headers to send to the endpoint. | -| `--sse-port ` | Start the server using the SSE transport on the given port (default: 5000). | -| `--sse-address ` | The IP address to bind the SSE server to (default: 127.0.0.1). | -| `--http-port ` | Start the server using the Streamable HTTP transport on the given port (default: 5000). | -| `--http-address ` | The IP address to bind the Streamable HTTP server to (default: 127.0.0.1). | -| `-i, --introspection` | Expose the schema to the MCP client through `introspect` and `execute` tools. [Learn more](/apollo-mcp-server/guides/#from-schema-introspection). | -| `--uplink-manifest` | Enable use of uplink to get the persisted queries (requires `APOLLO_KEY` and `APOLLO_GRAPH_REF`). [Learn more](/apollo-mcp-server/guides/#from-graphos-managed-persisted-queries). | -| `-x, --explorer` | Expose a tool that returns the URL to open a GraphQL operation in Apollo Explorer (requires `APOLLO_GRAPH_REF`). | -| `-o, --operations [...]` | Operation files to expose as MCP tools. [Learn more](/apollo-mcp-server/guides/#from-operation-files). | -| `--manifest ` | The path to the persisted query manifest containing operations. | -| `--collection ` | The ID of an operation collection to use as the source for operations (requires `APOLLO_KEY`). If `default` is used instead of an ID, the MCP Tools for `APOLLO_GRAPH_REF` will be used as the source. [Learn more](/apollo-mcp-server/guides/#from-operation-collection) | -| `--disable-type-description` | Disable operation root field types in tool description. | -| `--disable-schema-description` | Disable schema type definitions referenced by all fields returned by the operation in the tool description. | -| `-m, --allow-mutations ` | [default: `none`]

Possible values:
  • `none`: Don't allow any mutations
  • `explicit`: Allow explicit mutations, but don't allow the LLM to build them
  • `all`: Allow the LLM to build mutations
| -| `-l, --log ` | [default: `INFO`]

Possible values:
  • `TRACE`
  • `DEBUG`
  • `INFO`
  • `WARN`
  • `ERROR`
| -| `-h, --help` | Print help (see a summary with `-h`). | -| `-V, --version` | Print version | - -Specifying either the SSE port or address (or both) will enable the SSE transport. -Specifying either the HTTP port or address (or both) will enable the Streamable HTTP transport. +### CLI options + +| Option | Description | +| :-------------- | :------------------------ | +| `-h, --help` | Print help information | +| `-V, --version` | Print version information | + +### Config options + +All fields are optional and have sensible default values. + +| Option | Type | Default | Description | +| :--------------- | :-------------------- | :----------------------- | :------------------------------------------------------------ | +| `custom_scalars` | `FilePath` | | Path to a custom scalar map | +| `endpoint` | `URL` | `http://localhost:4000/` | The target GraphQL endpoint | +| `graphos` | `GraphOS` | | Apollo-specific credential overrides | +| `headers` | `Map` | `{}` | List of hard-coded headers to include in all GraphQL requests | +| `introspection` | `Introspection` | | Introspection configuration | +| `logging` | `Logging` | | Logging configuration | +| `operations` | `OperationSource` | | Operations configuration | +| `overrides` | `Overrides` | | Overrides for server behavior | +| `schema` | `SchemaSource` | | Schema configuration | +| `transport` | `Transport` | | The type of server transport to use | + + +#### GraphOS configuration + +These fields are under the top-level `graphos` key. + +| Option | Type | Default | Description | +| :------------------------ | :------- | :------ | :-------------------------------------------------------------------------------------------------------------- | +| `apollo_key` | `string` | | The Apollo GraphOS key. You can also provide this with the `APOLLO_KEY` environment variable | +| `apollo_graph_ref` | `string` | | The Apollo GraphOS graph reference. You can also provide this with the `APOLLO_GRAPH_REF` environment variable | +| `apollo_registry_url` | `URL` | | The URL to use for Apollo's registry | +| `apollo_uplink_endpoints` | `URL` | | List of uplink URL overrides. You can also provide this with the `APOLLO_UPLINK_ENDPOINTS` environment variable | + + +#### Introspection configuration + +These fields are under the top-level `introspection` key. + +| Option | Type | Default | Description | +| :------------------- | :------- | :------ | :-------------------------------------------------------------------- | +| `execute` | `object` | | Execution configuration for introspection | +| `execute.enabled` | `bool` | `false` | Enable introspection for execution | +| `introspect` | `object` | | Introspection configuration for allowing clients to run introspection | +| `introspect.enabled` | `bool` | `false` | Enable introspection requests | +| `search` | `object` | | Search tool configuration | +| `search.enabled` | `bool` | `false` | Enable search tool | + + +#### Logging configuration + +These fields are under the top-level `logging` key. + +| Option | Type | Default | Description | +| :------ | :-------------------------------------------------- | :------- | :------------------------------ | +| `level` | `oneOf ["trace", "debug", "info", "warn", "error"]` | `"info"` | The minimum log level to record | + + +#### Operation source configuration + +These fields are under the top-level `operations` key. The available fields depend on the value of the nested `source` key. +The default value for `source` is `"infer"`. + +| Source | Option | Type | Default | Description | +| :----------------- | :------- | :--------------- | :------ | :------------------------------------------------------------------------------------------------------------------------------------------------ | +| GraphOS Collection | `source` | `"collection"` | | Load operations from a GraphOS collection | +| GraphOS Collection | `id` | `string` | | The collection ID to use in GraphOS. Use `default` for the default collection. [Learn more](/apollo-mcp-server/guides/#from-operation-collection) | +| Introspection | `source` | `"introspect"` | | Load operations by introspecting the schema. Note: You must enable introspection to use this source | +| Local | `source` | `"local"` | | Load operations from local GraphQL files or directories | +| Local | `paths` | `List` | | Paths to GraphQL files or directories to search | +| Manifest | `source` | `"manifest"` | | Load operations from a persisted queries manifest file | +| Manifest | `path` | `FilePath` | | The path to the persisted query manifest | +| Uplink | `source` | `"uplink"` | | Load operations from an uplink manifest. Note: This source requires an Apollo key and graph reference | +| Infer | `source` | `"infer"` | * | Infer where to load operations based on other configuration options. | + + +#### Overrides configuration + +These fields are under the top-level `overrides` key. + +| Option | Type | Default | Description | +| :--------------------------- | :---------------------------------- | :------- | :------------------------------------------------------------------------------------------------------------------------------- | +| `disable_type_description` | `bool` | `false` | Disable type descriptions to save on context-window space | +| `disable_schema_description` | `bool` | `false` | Disable schema descriptions to save on context-window space | +| `enable_explorer` | `bool` | `false` | Expose a tool that returns the URL to open a GraphQL operation in Apollo Explorer. Note: This requires a GraphOS graph reference | +| `mutation_mode` | `oneOf ["none", "explicit", "all"]` | `"none"` | Defines the mutation access level for the MCP server | + + +#### Schema source configuration + +These fields are under the top-level `schema` key. The available fields depend on the value of the nested `source` key. +The default value for `source` is `"uplink"`. + +| Source | Option | Type | Default | Description | +| :----- | :------- | :--------- | :------ | :---------------------------------------------------------------------------------- | +| Local | `source` | `"local"` | | Load schema from local file | +| Local | `path` | `FilePath` | | Path to the GraphQL schema | +| Uplink | `source` | `"uplink"` | * | Fetch the schema from uplink. Note: This requires an Apollo key and graph reference | + + +#### Transport configuration + +These fields are under the top-level `transport` key. The available fields depend on the value of the nested `type` key. +The default value for `type` is `"stdio"`. + +| Type | Option | Type | Default | Description | +| :------------- | :-------- | :------------------ | :---------- | :---------------------------------------------------------------------------------------------------------------------------- | +| stdio | `type` | `"stdio"` | * | Use standard IO for communication between the server and client | +| SSE | `type` | `"sse"` | | Host the MCP server on the supplied configuration, using SSE for communication. Note: Deprecated in favor of `StreamableHTTP` | +| SSE | `address` | `IpAddr` | `127.0.0.1` | The IP address to bind to | +| SSE | `port` | `u16` | `5000` | The port to bind to | +| StreamableHTTP | `type` | `"streamable_http"` | | Host the MCP server on the configuration, using streamable HTTP messages. | +| StreamableHTTP | `address` | `IpAddr` | `127.0.0.1` | The IP address to bind to | +| StreamableHTTP | `port` | `u16` | `5000` | The port to bind to | + ### Mapping rover dev options @@ -128,19 +219,6 @@ Running `rover dev --mcp` starts an MCP Server. Additional options, `--mcp*`, di The mapping of `rover dev` options to MCP Server options: -| `rover dev` option | Equivalent MCP Server option | -| :---------------------------------------------------- | :---------------------------------------------------- | -| `--mcp-directory ` | `-d, --directory ` | -| `--mcp-port ` | `--http-port ` | -| `--mcp-address
` | `--http-address
` | -| `--mcp-explorer` | `-x, --explorer` | -| `--mcp-introspection` | `-i, --introspection` | -| `--mcp-uplink-manifest` | `-u, --uplink-manifest` | -| `--mcp-operations [...]` | `-o, --operations [...]` | -| `--mcp-header ` | `--header ` | -| `--mcp-manifest ` | `--manifest ` | -| `--mcp-collection ` | `--collection ` | -| `--mcp-custom-scalars-config ` | `-c, --custom-scalars-config ` | -| `--mcp-allow-mutations ` | `-m, --allow-mutations ` | -| `--mcp-disable-type-description` | `--disable-type-description` | -| `--mcp-disable-schema-description` | `--disable-schema-description` | +| `rover dev` option | Equivalent MCP Server option | Description | +| :------------------------------ | :--------------------------- | :---------------------------------------- | +| `--mcp-config ` | `` | Path to the MCP server configuration file | diff --git a/docs/source/guides/index.mdx b/docs/source/guides/index.mdx index 962622e5..55378fe0 100644 --- a/docs/source/guides/index.mdx +++ b/docs/source/guides/index.mdx @@ -18,13 +18,13 @@ Here is the typical workflow for developing with Apollo MCP Server: ## Set up graph -An Apollo MCP Server must know the schema of GraphQL API it supports. You can use either [the `--schema` option to provide the schema or `--apollo-graph-ref` and `--apollo-key` options to get the schema from uplink](/apollo-mcp-server/command-reference#options). If using `--schema` option, it can be either an API or supergraph schema. +An Apollo MCP Server must know the schema of GraphQL API it supports. You can use either [the `schema` option to provide the schema or `graphos.apollo-graph-ref` and `graphos.apollo-key` options to get the schema from uplink](/apollo-mcp-server/command-reference#options). If using `schema` option, it can be either an API or supergraph schema. The schema is required for three main purposes: 1. **Tool Descriptions**: The schema provides type information used to generate tool descriptions. You can override these descriptions by adding comments to your operation files. 1. **Input Validation**: The schema is used to translate GraphQL input types into JSON Schema, ensuring that AI models provide correctly formatted inputs. -1. **Introspection Support**: If you enable the `--introspection` option, the schema is used to provide information about available types and operations to AI models. +1. **Introspection Support**: If you enable the `introspection` option, the schema is used to provide information about available types and operations to AI models. ## Define GraphQL operations for tools @@ -65,11 +65,11 @@ query GetAllWeatherData($coordinate: InputCoordinate!, $state: String!) { -The `--operations` option of the MCP Server provides it with a list of operation files. For each operation file you provide, the MCP Server creates an MCP tool that calls the corresponding GraphQL operation. +Use the `operations` option to provide the MCP Server with a list of operation files. For each operation file you provide, the MCP Server creates an MCP tool that calls the corresponding GraphQL operation. -The `--operations` option can also be used to specify a directory. All files with a `.graphql` extension in the directory will be loaded as operations. +You can also use the `operations` option to specify a directory. The server then loads all files with a `.graphql` extension in that directory as operations. -Files and directories specified with `--operations` will be hot reloaded. When specifying a file, the MCP tool will be updated when the file contents are modified. When specifying a directory, operations exposed as MCP tools will be updated when files are added, modified, or removed from the directory. +Files and directories specified with `operations` are hot reloaded. When you specify a file, the MCP tool is updated when the file contents are modified. When you specify a directory, operations exposed as MCP tools are updated when files are added, modified, or removed from the directory. ### From Operation Collection @@ -79,14 +79,13 @@ To use a GraphOS Operation Collection, you must: - Set `APOLLO_GRAPH_REF` and `APOLLO_KEY` environment variables for a GraphOS graph -Each variant will have it's own default MCP Tools Collection, but you can specify any shared collection by using `--collection `. -Apollo MCP Server will automatically fetch the default collection if no id is specified. +Each variant will have its own default MCP Tools Collection, but you can specify any shared collection by using `operations` with `operations.source: collection`. +Apollo MCP Server automatically fetches the default collection if no ID is specified. -```sh title="Example command using a GraphOS Operation Collection" -apollo-mcp-server \ - --directory \ - --schema graphql/weather/api.graphql \ - --collection +```yaml title="Example config file for using a GraphOS Operation Collection" +operations: + source: collection + id: ``` The MCP Server supports hot reloading of the GraphOS Operation Collection, so it can automatically pick up changes from GraphOS without restarting. @@ -95,7 +94,7 @@ The MCP Server supports hot reloading of the GraphOS Operation Collection, so it Apollo MCP Server supports reading GraphQL operations from Apollo-formatted [persisted query manifest](/graphos/platform/security/persisted-queries#manifest-format) files. -You can set the persisted query manifest file for the MCP Server by using the `--manifest` option. The MCP Server supports hot reloading of persisted query manifests, so changes to manifests are applied without restarting. +Set the persisted query manifest file for the MCP Server with the `operations` option. The MCP Server supports hot reloading of persisted query manifests, so changes to manifests are applied without restarting. An example manifest is available in the [GitHub repo](https://github.com/apollographql/apollo-mcp-server/tree/main/graphql/weather/persisted_queries). @@ -103,12 +102,19 @@ An example manifest is available in the [GitHub repo](https://github.com/apollog From the root of a local MCP Server repo, run the `apollo-mcp-server` binary with the example persisted query manifest, `graphql/weather/persisted_queries/apollo.json`: +```yaml title="Example config for using Persisted Query Manifest" +headers: + 'apollographql-client-name': 'my-web-app' +operations: + source: manifest + path: /graphql/weather/persisted_queries/apollo.json +schema: + source: local + path: /graphql/weather/api.graphql +``` + ```sh showLineNumbers=false -apollo-mcp-server \ - --directory \ - --schema graphql/weather/api.graphql \ - --header "apollographql-client-name:my-web-app" \ - --manifest graphql/weather/persisted_queries/apollo.json +apollo-mcp-server ``` @@ -120,7 +126,6 @@ For graphs managed by GraphOS, Apollo MCP Server can get operations by reading p To use GraphOS persisted queries, you must: - Set `APOLLO_GRAPH_REF` and `APOLLO_KEY` environment variables for a GraphOS graph -- Run Apollo MCP Server with the `--uplink-manifest` option @@ -128,25 +133,31 @@ Use a [contract variant](/graphos/platform/schema-management/delivery/contracts/ +```yaml title="Example config using GraphOS-managed persisted queries" +headers: + 'apollographql-client-name': 'my-web-app' +operations: + source: uplink +schema: + source: local + path: /graphql/weather/api.graphql +``` + ```sh title="Example command using GraphOS-managed persisted queries" -apollo-mcp-server \ - --directory \ - --schema graphql/weather/api.graphql \ - --header "apollographql-client-name:my-web-app" \ - --uplink-manifest +apollo-mcp-server ``` The MCP Server supports hot reloading of GraphOS-managed persisted queries, so it can automatically pick up changes from GraphOS without restarting. If you register a persisted query with a specific client name instead of `null`, you must configure the MCP Server to send the necessary header indicating the client name to the router. -Use the `--header` option when running the MCP Server to pass the header to the router. The default name of the header expected by the router is `apollographql-client-name`. To use a different header name, configure `telemetry.apollo.client_name_header` in router YAML configuration. +Use the `headers` option when running the MCP Server to pass the header to the router. The default name of the header expected by the router is `apollographql-client-name`. To use a different header name, configure `telemetry.apollo.client_name_header` in router YAML configuration. ### From schema introspection For use cases where not all operations can be pre-defined, Apollo MCP Server supports tool creation based on introspection of the graph schema. This allows AI agents to explore a graph and execute operations dynamically. -To enable these schema-aware tools, run the MCP Server with the `--introspection` option, which exposes two new tools: +To enable these schema-aware tools, run the MCP Server with the `introspection` option, which exposes two new tools: - `introspect` - returns information about schema types - `execute` - executes an operation on the GraphQL endpoint @@ -158,6 +169,19 @@ The MCP client can use these tools to provide schema information to the model an Use a [contract variant](/graphos/platform/schema-management/delivery/contracts/overview) so you can control the parts of your graph that AI can introspect. [Learn more](/apollo-mcp-server/best-practices#use-contract-variants-to-control-ai-access-to-graphs) + +```yaml title="Example config using introspection" +introspection: + execute: + enabled: true + introspect: + enabled: true +``` + +```sh title="Example command using introspection" +apollo-mcp-server +``` + {/* ### Documenting tools @@ -166,7 +190,7 @@ TODO ## Deploying the MCP server -There are two ways to deploy and operate the MCP server. +There are two ways to deploy and operate the MCP server. 1. Using the [MCP server container](#deploying-the-mcp-server-container) or binary, which connects to an existing GraphQL API endpoint 1. Using the [Apollo Runtime container](#deploying-mcp-using-the-apollo-runtime-container), which includes both an MCP server as well as the Apollo router @@ -181,16 +205,25 @@ and that clients will use the Streamable HTTP transport on container port 5000. An example `docker run` command that runs the MCP Server for the space dev example: +```yaml title="Example config for using Docker" +endpoint: https://thespacedevs-production.up.railway.app/ +operations: + source: local + paths: + - /data/operations/ +schema: + source: local + path: /data/api.graphql +``` + ```sh showLineNumbers=false docker run \ -it --rm \ --name apollo-mcp-server \ -p 5000:5000 \ + -v :/config.yaml \ -v $PWD/graphql/TheSpaceDevs:/data \ - ghcr.io/apollographql/apollo-mcp-server:latest \ - --schema api.graphql \ - --operations operations/ \ - --endpoint https://thespacedevs-production.up.railway.app/ + ghcr.io/apollographql/apollo-mcp-server:latest /config.yaml ``` ### Deploying MCP using the Apollo Runtime container @@ -199,7 +232,7 @@ The Apollo Runtime container includes all services necessary to serve GraphQL an To serve both MCP and GraphQL requests, both port `4000` and `5000` will need to be exposed. An example command which retrieves the schema from Uplink is: -```bash title="Docker" {3, 6} +```bash title="Docker" {3, 6} docker run \ -p 4000:4000 \ -p 5000:5000 \ @@ -222,12 +255,21 @@ You can inspect a local Apollo MCP Server by running it with MCP Inspector. 1. Run the MCP Server with Inspector: +```yaml title="Example config for debugging over stdio" +operations: + source: local + paths: + - /graphql/weather/operations/ +schema: + source: local + path: /graphql/weather/api.graphql +transport: + type: stdio +``` + ```sh npx @modelcontextprotocol/inspector \ - target/debug/apollo-mcp-server \ - --directory \ - --schema graphql/weather/api.graphql \ - --operations graphql/weather/operations + target/debug/apollo-mcp-server ``` @@ -254,12 +296,22 @@ You can also deploy the server as a container using the instructions in [Deployi +```yaml title="Example config for running in Streamable HTTP" +operations: + source: local + paths: + - /graphql/weather/operations/ +schema: + source: local + path: /graphql/weather/api.graphql +transport: + type: streamable_http + address: 127.0.0.1 + port: 5000 +``` + ```sh -target/debug/apollo-mcp-server \ - --directory \ - --http-port 5000 \ - --schema graphql/weather/api.graphql \ - --operations graphql/weather/operations +target/debug/apollo-mcp-server ``` 1. Start the MCP Inspector: @@ -271,7 +323,7 @@ npx @modelcontextprotocol/inspector 1. In a browser, go to the URL returned by Inspector, then fill in the details: - **Transport Type**: Select `Streamable HTTP` - - **URL**: Enter `http://127.0.0.1:5000/mcp`, where the port must match the `--http-port` option + - **URL**: Enter `http://127.0.0.1:5000/mcp`, where the port must match the `transport.port` option 1. Click **Connect** and **List Tools**. You should see the tools for the operations you provided. diff --git a/docs/source/quickstart.mdx b/docs/source/quickstart.mdx index 27136756..878edda9 100644 --- a/docs/source/quickstart.mdx +++ b/docs/source/quickstart.mdx @@ -25,7 +25,7 @@ In this quickstart, you'll create a working AI integration where Claude Desktop Here's what the end result looks like: -> **You**: "Tell me about the astronauts currently in space" +> **You**: "Tell me about the astronauts currently in space" > **Claude**: *[Uses GetAstronautsCurrentlyInSpace tool]* "There are currently 7 astronauts aboard the International Space Station..." This example uses a pre-built space API, but the same approach works with any GraphQL API - including your own production services. @@ -50,7 +50,7 @@ The example files located in `graphql/TheSpaceDevs/` include: - `supergraph.yaml` is a [supergraph configuration file](/rover/commands/supergraphs#yaml-configuration-file) used by the Rover CLI - **4 pre-built operations** that become your AI tools: - `ExploreCelestialBodies` - Search planets, moons, and stars - - `GetAstronautDetails` - Get info about specific astronauts + - `GetAstronautDetails` - Get info about specific astronauts - `GetAstronautsCurrentlyInSpace` - See who's in space right now - `SearchUpcomingLaunches` - Find upcoming rocket launches @@ -58,10 +58,17 @@ The example files located in `graphql/TheSpaceDevs/` include: 1. From the root directory of your local repo, run `rover dev` to start a local graph with an MCP Server: + ```yaml title="Config file" + operations: + source: local + paths: + - ./graphql/TheSpaceDevs/operations + ``` + ```sh showLineNumbers=false rover dev --supergraph-config ./graphql/TheSpaceDevs/supergraph.yaml \ --mcp \ - --mcp-operations ./graphql/TheSpaceDevs/operations + --mcp-config ``` This command: @@ -140,7 +147,7 @@ Let's verify everything is working: #### MCP Server Won't Start - **Error**: "Port 5000 is already in use" - - Solution: Kill any existing processes using port 5000 or specify a different port with `--mcp-sse-port` flag using Rover Dev or `--sse-port` when running the MCP server directly + - Solution: Kill any existing processes using port 5000 or specify a different port with the `transport.port` option or `APOLLO_MCP_TRANSPORT__PORT` env variable - **Error**: "Failed to load supergraph configuration" - Solution: Verify you're running the command from the repo root directory - Solution: Check that the path to `supergraph.yaml` is correct @@ -205,12 +212,21 @@ You can run the MCP Server using STDIO transport instead of Streamable HTTP. Thi 1. Download the binary of the latest version of Apollo MCP Server 2. Use MCP Inspector to run the server: + ```yaml title="Config for stdio transport" + endpoint: https://thespacedevs-production.up.railway.app/ + operations: + source: local + paths: + - /operations + schema: + source: local + path: /api.graphql + transport: + type: stdio + ``` + ```sh - npx @modelcontextprotocol/inspector apollo-mcp-server \ - --directory \ - --schema api.graphql \ - --operations operations \ - --endpoint https://thespacedevs-production.up.railway.app/ + npx @modelcontextprotocol/inspector apollo-mcp-server ``` 3. Configure Claude Desktop to use STDIO: @@ -221,18 +237,11 @@ You can run the MCP Server using STDIO transport instead of Streamable HTTP. Thi "thespacedevs": { "command": "", "args": [ - "--directory", - "", - "--schema", - "api.graphql", - "--operations", - "operations", - "--endpoint", - "https://thespacedevs-production.up.railway.app/" + "" ] } } } ``` - + diff --git a/scripts/nix/install.sh b/scripts/nix/install.sh index e9ba409f..dae6822d 100755 --- a/scripts/nix/install.sh +++ b/scripts/nix/install.sh @@ -14,7 +14,7 @@ BINARY_DOWNLOAD_PREFIX="${APOLLO_MCP_SERVER_BINARY_DOWNLOAD_PREFIX:="https://git # Apollo MCP Server version defined in apollo-mcp-server's Cargo.toml # Note: Change this line manually during the release steps. -PACKAGE_VERSION="v0.5.2" +PACKAGE_VERSION="v0.6.0" download_binary_and_run_installer() { downloader --check diff --git a/scripts/windows/install.ps1 b/scripts/windows/install.ps1 index bdb4947c..c6fc55e9 100644 --- a/scripts/windows/install.ps1 +++ b/scripts/windows/install.ps1 @@ -8,7 +8,7 @@ # Apollo MCP Server version defined in apollo-mcp-server's Cargo.toml # Note: Change this line manually during the release steps. -$package_version = 'v0.5.2' +$package_version = 'v0.6.0' function Install-Binary($apollo_mcp_server_install_args) { $old_erroractionpreference = $ErrorActionPreference