Repository navigation
Package Model
This page describes how the Zig package bridge_sdk holds the bridges. The package has one core module, bridge, and one module and one executable for each product. The key of a bridge is the name of its product, after a check of the brand guidelines that the vendor publishes. The package also exports the mcp module of zig-sdk. An embedder takes mcp from the package, so that it uses only one zig-sdk. The page also gives the steps to add a bridge and the record of each brand check.
Applies to: zig-bridge-sdk 0.1.2 on main at commit 3cbc34b, the commit of the tag v0.1.2, with the milestones M0 to M6. zig-sdk 0.5.1 at commit 52fc1b8, the commit of the tag v0.5.1. Zig 0.16.01.
The repository is one Zig package2 with the name bridge_sdk. Its build.zig.zon has the version 0.1.2 and the minimum_zig_version 0.16.0. The only dependency is mcp, the package of zig-sdk. build.zig.zon pins it with a git+https URL with the commit 52fc1b8 of the tag v0.5.1, and with the hash of the package. The .paths list has build.zig, build.zig.zon, src, bridges, LICENSE, NOTICE and README.md.
| Name | Kind | Root source file | Imports |
|---|---|---|---|
bridge |
Module | src/bridge.zig |
mcp and build_options
|
vscode |
Module | bridges/vscode/vscode.zig |
mcp and bridge
|
mcp |
Module | The root of the pinned zig-sdk | None |
mcp-bridge-vscode |
Executable | bridges/vscode/main.zig |
vscode, bridge and mcp
|
build_options gives the version of the package to bridge.version. mcp-bridge-vscode --version shows it. The initialize result also has it when the upstream server sends no server information. The build also makes two executables for the tests. bridge-fixture-server is the upstream server of the tests, and only the step fixture-server installs it. bridge-embedded-server is the same server with the vscode bridge in its process (M5), and only the step embedded-server installs it.
The Architecture page describes the modules of the core and the path of a request.
Each bridge has a key. The key names the directory bridges/<key>/, the module <key> and the executable mcp-bridge-<key>. The module declares the settings of the product as one bridge.Profile. The first bridge is for Visual Studio Code (VS Code), with the key vscode.
| Part | The vscode bridge |
|---|---|
| Directory | bridges/vscode/ |
| Module |
vscode, with the root bridges/vscode/vscode.zig
|
| Executable |
mcp-bridge-vscode, with the root bridges/vscode/main.zig and the command line in bridges/vscode/cli.zig
|
| Profile | vscode.profile |
| OAuth identity |
vscode.identity: the client name mcp-bridge-vscode (zig-bridge-sdk), the keychain service zig-bridge-sdk/mcp-bridge-vscode and the token directory zig-bridge-sdk/vscode/tokens (M4) |
| Redirect port | 41894 (M4) |
| Client ID metadata document |
site/vscode/client.json. GitHub Pages publishes it at https://christianpresley.github.io/zig-bridge-sdk/vscode/client.json, the value of vscode.client_metadata_url (M4). |
| API for a zig-sdk server |
vscode.serveStdio and vscode.StdioOptions (M5) |
| Tests |
bridges/vscode/test/, and the build step test-vscode
|
| Run step | run-vscode |
| README | bridges/vscode/README.md |
The product is a property of the executable. The core never chooses a profile from the clientInfo of the client, and the package has no generic profile. The .paths list, the fmt step and lint-docs include all of bridges/.
bridge.Profile in src/bridge.zig holds the settings of one product. bridge.Frontend and bridge.translate take it as *const Profile. vscode.serve gives &vscode.profile to Frontend.init.
| Field | Default | Use | Value in vscode.profile
|
|---|---|---|---|
name |
None | The name of the executable. Each log line has it as its tag, and --version shows it. The initialize result has it when the upstream server sends no server information and the fallback name is empty. |
mcp-bridge-vscode |
reply_protocol_version |
"2025-11-25" |
The protocolVersion of the initialize result3. |
The default |
request_id_prefix |
"b-" |
The prefix of the string ids of the requests of the bridge to the client. | The default |
meta_passthrough.keys |
No keys | The _meta keys of a client request that go to the upstream server. |
traceparent and tracestate
|
meta_passthrough.prefixes |
No prefixes | The _meta key prefixes of a client request that go to the upstream server. |
vscode. |
quirks.normalize_array_items |
false |
Each array schema of a tool inputSchema without items gets items: {}. |
true |
quirks.drop_non_object_output_schema |
false |
Each tool loses an outputSchema whose root does not have type: "object". |
true |
quirks.strict_legacy_results |
false |
Remove the values of revision 2026-07-28 that revision 2025-11-25 does not allow in a result. | false |
Profile.MetaPassthrough.allows gives true for a key in keys and for a key that starts with a prefix in prefixes. translate.passMeta then also removes each key that mcp.protocol.meta.validateKey refuses. It also removes each key of zig-sdk and each key with a reserved prefix.
The values of vscode.profile have these reasons, from the comments of bridges/vscode/vscode.zig:
-
normalize_array_items: the Copilot extension of VS Code stops each request when an array schema has noitems4. -
drop_non_object_output_schema: VS Code does not read the output schema. The TypeScript SDK 1.x refuses atools/listresult with an output schema that is not an object schema. -
strict_legacy_resultsis off: VS Code reads the results of revision 2026-07-28, and the MCP Apps5 need them without a change.
These settings are not in the profile. bridge.Frontend.Options holds them for each connection:
-
capability_maskandreply_mask: the capabilities for the upstream server, and the capabilities for theinitializeresult. -
fallback_name: theserverInfo.namewhen the upstream server sends none.mcp-bridge-vscodetakes it from--name, from the file name of the upstream command without its extension, or from the host of the URL. The embedded bridge takes the name of the server. -
timeouts,discover_timeout,max_line_bytes,json_max_depth,max_in_flight_requests,shutdown_graceandmax_input_requests_per_round. The embedded bridge takes the limits from the server. -
listen_backoffandlisten_max_backoff: the waits before a new listen stream. -
sign_in: thebridge.oauth.Authorizerof an HTTP upstream server (M4), or null.
Two more settings are not in the profile:
- The OAuth identity (M4).
bridge.oauth.Identityholds the client name, the keychain service, the product of the token directory and the default client ID metadata document.vscode.identityis the identity of thevscodebridge. - The discover option of the embedded bridge (M5).
bridge.embed.Options.discoverandvscode.StdioOptions.discoverhold it:.answer, the default, or.refuse.
build.zig exports the mcp module of the pinned zig-sdk with b.modules.put(b.graph.arena, "mcp", mcp). In the source code, bridge.mcp and vscode.mcp are the same module. An embedder is a package that uses a bridge module and the mcp module together. From milestone M5, vscode.serveStdio puts the bridge into the executable of a zig-sdk server, and it takes the *mcp.Server of the package.
An embedder must use exactly one zig-sdk: the commit and the hash in the build.zig.zon of bridge_sdk. Do one of these steps:
- Get
mcpfrom the package:b.dependency("bridge_sdk", .{ .target = target, .optimize = optimize }).module("mcp")inbuild.zig. In the source code,@import("vscode").mcpis the same module. - Pin the zig-sdk commit and hash of
bridge_sdk. Giveb.dependencythe same.targetand.optimizearguments for zig-sdk and forbridge_sdk.
When the two mcp modules are not the same, Zig 0.16.0 shows one of these errors:
| Error | Cause |
|---|---|
expected type '*mcp.server.Server', found '*mcp.server.Server' |
The package has a second zig-sdk, for example from a different commit. The types of the two mcp modules are then different. |
file exists in modules 'mcp' and 'mcp0' |
The package pins the same zig-sdk, but it gives b.dependency different arguments. Zig then makes two mcp modules from the same files. |
The example in examples/consumer/ takes vscode and mcp from the package. It is a zig-sdk server that calls vscode.serveStdio. A comptime check stops its build when vscode.mcp is not its mcp. The CI job consumer builds the example from a tarball of the commit, so the job also checks the .paths list.
A change of the zig-sdk pin is a minor release of zig-bridge-sdk. From milestone M5, the mcp types are a part of the public API of the vscode module. The repository file VERSIONING.md gives the rules of the pin.
- Read the brand guidelines and the trademark guidelines that the vendor of the product publishes.
- Select the key from the result of that check.
- Record the result, the URL and the date of the check in the section Brand checks.
- Make the directory
bridges/<key>/for all files of the bridge. - Write the module
bridges/<key>/<key>.zig. Declarepub const profile: bridge.Profileand aservefunction. - In the module, export
mcpandbridgeagain, asbridges/vscode/vscode.zigdoes. - For the URL form, declare
pub const identitywithbridge.oauth.Identity.of. - Give the bridge its own redirect port. The
vscodebridge uses the port 41894. - Put the client ID metadata document of the bridge in
site/<key>/client.json, with a test. - Write a
serveStdiofunction that callsbridge.embed.serveStdioAutowith the profile of the bridge. - Write a short
bridges/<key>/main.zig. Setstd_options.logFntobridge.log.tagged(profile.name). - Use the exit codes of
mcp-bridge-vscode: 0 at the end of stdin, 1 for a failure, 2 for bad arguments. - In
build.zig, add the module<key>with the importsmcpandbridge. - In
build.zig, add the executablemcp-bridge-<key>and the stepsrun-<key>andtest-<key>. - Add the tests of the module and of the executable to the step
test. - Write transcript tests in
bridges/<key>/test/. Give them the vendored schemas withaddSchemaImportsinbuild.zig. - Check each frame of the bridge against the schemas of the two revisions.
- Write
bridges/<key>/README.mdwith the build, the configuration of the client and the trademark notice. - Write a wiki page for the bridge. Add a row to the table of bridges on Home.
- Add the entries of the bridge to
CHANGELOG.mdunder[Unreleased], with the key as the part. - Run
zig build fmt test lint-docs.
The command line parser of the vscode bridge is in bridges/vscode/cli.zig. The plan moves the shared parts of the command line into the core only when a second product comes.
Before a key goes into the names of a bridge, the project reads the brand guidelines of the vendor. This section records each check. A record is not legal advice.
| Item | Record |
|---|---|
| Product | Visual Studio Code (VS Code), from Microsoft |
| Guidelines | The brand guidelines of VS Code6, and the trademark guidelines of Microsoft7 |
| URL |
https://code.visualstudio.com/brand and https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks
|
| Date of the check | 2026-10-06 |
| Result | The brand page does not allow the product name in the name of a product or service, on a website or in a domain name. For content that works with VS Code, it approves names of the form <name> for Visual Studio Code. The trademark guidelines of Microsoft ask for a trademark notice. They do not allow text that suggests an affiliation with Microsoft or an endorsement by Microsoft. The brand page also asks writers not to use the forms vscode, VSCode, VSC or Code for the product. |
| Decision | The approved plan of the project, 2026-10-06. Keep the key vscode for the module, the directory bridges/vscode/ and the executable mcp-bridge-vscode. Add a trademark notice. |
The decision came before milestone M0, because M0 made these names. A later change of the key changes the paths in VS Code configurations, the imports of embedders and the groups of released changelog entries. The project applies these rules for the decision:
- Prose writes "Visual Studio Code (VS Code)" at the first mention on a page, and "VS Code" after it.
- Prose writes the key, the module and the executable only as code spans. The project dictionary has
vscodeandvscas synonyms of VS Code, solint-docsfinds them in plain prose. - Titles use the form
<name> for Visual Studio Code, for example "Thevscodebridge for Visual Studio Code". - The trademark notice is in
README.md, inbridges/vscode/README.md, in the doc comment ofbridges/vscode/vscode.zigand in the footer of this wiki.
The notice has this text:
Visual Studio Code and VS Code are trademarks of Microsoft Corporation. This project has no affiliation with Microsoft, and Microsoft does not endorse it.
This record is not legal advice.
- ZIG-0.16-RELNOTES: Zig 0.16.0 release notes.
- ZIG-BUILD-GUIDE: The build system of Zig.
- MCP-CHANGELOG-2025-11-25: Key changes of revision 2025-11-25.
-
VS Code issue 339276: An array parameter without
itemsblocks the tools of a server. - MCP-EXT-APPS: The MCP Apps extension.
- Visual Studio Code brand guidelines: The brand page of VS Code, with the rules for the product name.
- Microsoft trademark guidelines: The rules of Microsoft for the use of its trademarks.
zig-bridge-sdk uses the Apache License 2.0. The wiki uses the project profile of ASD-STE100 Simplified Technical English. Visual Studio Code and VS Code are trademarks of Microsoft Corporation. This project has no affiliation with Microsoft, and Microsoft does not endorse it.
zig-bridge-sdk
zig-sdk