This is in part why I've been developing inside a VM for the last 2 years. Interestingly, VS Code has nice support for installing and running extensions on the remote. Only themes live on the host.
HN user
disintegrator
I work at Speakeasy (https://speakeasy.com) on code generation. Most of time is spent with TypeScript then Go.
Yep, no dispute here. It's just that my and other people's experience is that SOC2 controls are usually passed down by edict and whether you review before or after merge, there's typically (from my experiences at SaaS/Fintech) some form of reviews happening. I've done both styles in the same company for different reasons.
I generally think most of the points made in the article are a little too extreme. Even feature flags are valuable if you’re trying to get something up for certain key customers to give feedback on while you iterate as an example. There is some hygiene required around maintaining and removing flags but I think that’s in the same bucket as writing tests, updating dependencies and refactoring code: worthwhile effort that additionally unlocks testing in production.
My understanding is code reviews are needed as part of SOC-2 compliance. More to supplement automated testing than explicitly mandated. In other words, it makes auditors happy to check off the requirement about verifying changes going to prod.
The remarks about code comments are little too extreme in my opinion. Some code can be difficult to understand at face value. Like I’m writing a Vite plugin and it has code like this:
const moduleId = "virtual:mypkg";
const resolvedModuleId = "\0" + moduleId;
Unless you’ve written Vite/rollup plugins, which many folks haven’t, you’re going to appreciate a comment that at least points to some docs.If anything, succinct code comments that explain obscure conventions or describe relevant critical requirements are worth their weight in gold because they are valuable tokens for a coding assistant.
Disclaimer: I work at Speakeasy but not the author.
It probably needs better wording because it's sort of the wrong complexity metric. Many customers have gigantic OpenAPI documents with large numbers of deep and wide JSON Schemas that contain things like allOf/oneOf/anyOf sub-schemas, all of which need to be parsed into an object model for use by downstream tooling (e.g. code generation). For those customers, we want generation time to be super speedy and since this is a core aspect of Speakeasy, it made a ton of sense to us to take full control of OpenAPI parsing and optimize it.
When you turn on exhaustive, exhaustruct and wrapcheck linters in golangci-lint. You get such a massive safety boost and it makes you fly through writing Go.
One of the team members working on Gram here.
I initially worked on a code generator for OpenAPI -> MCP in January but very quickly we found issues relating to poor quality operation (tool) names and descriptions. Not to mention that each API endpoint does not cleanly map to an MCP tool and yet it all gets dumped into the context window - sometimes exhausting it if you have hundreds of schemas and endpoints.
Gram is our attempt to make better use of API by adding a curation layer:
- You upload your OpenAPI document, or any number of other OpenAPI documents. - You then subset them into "toolsets" by selecting only the ones relevant to a domain (e.g. reading stripe charges) or business process (e.g. understanding customer health by reading info from your CRM, data warehouse and so on). - Optionally, you create custom tools (these are prompt templates under the hood) that describe how to make a series of tool calls to solve a problem. - Finally, every toolset is automatically exposed as a hosted/managed MCP server. No waiting for build or deploy steps. - You can edit the names and descriptions of all imported tools and they are instantly reflected in the MCP server.
The net result is you have a rapid iteration loop to create effective tools from your API.
I hope you have a chance to try it out. Will be around to answer any questions in the mean time :)
I just love how this language marches forward. I have so many colleagues that hate many aspects of it but I sit here combining Go, Goa and SQLc writing mountains of code and having a fairly good compiler behind me. I understand what I’m missing out on by not using stricter languages and so often it’s a totally fine trade off.
I know this won’t apply to everyone but I’ve been able to, relatively successfully, stick to the constraint that most of my dev tools are static binaries: zoxide, fzf, eza, btop and so on. There is one glaring exception which is docker but I let it pass.
By sticking to this I’m able to avoid Homebrew’s mess and Nix’s complexity. I use mise (https://mise.jdx.dev/) to manage the binaries and languages I have on my machine. It handles installing multiple versions and is directory-aware.
Not a Firefox user I take it?
The introduction of WWW-Authenticate challenge is so welcome. Now it's much clearer that the MCP server can punt the client to resource provider's OAuth flow and sit back waiting for an `Authorization: Bearer ...`.
It's somewhat disappointing to see a bunch of "well, duh" comments here. We're often asking for research and citations and this seems like a useful entry in the corpus of "effects of AI usage on cognition".
On the topic itself, I am very cautious about my use of LLMs. It breaks down into three categories for me: 1. replacing Google, 2. get a first review of my work and 3. taking away mundane tasks around code editing.
Point 3. is where I can become most complacent and increasingly miscategorize tasks as mundane. I often reflect after a day working with an LLM on coding tasks because I want to understand how my behavior is changing in its presence. However, I do not have a proper framework to work out "did i get better because of it or not".
I still believe we need to get better as professionals and it worries me that even this virtue is called into question nowadays. Research like this will be helpful to me personally.
VS Code seems to be working on it
https://www.epicai.pro/using-mcp-sampling-in-vs-code-insider...
If you limit yourself to common programming languages and single-binary programs (e.g. ones written in Rust/Go) then I cannot recommend Mise enough to you. Absolute bliss compared to homebrew, asdf and other projects especially if you want multiple versions of tools in different projects.
Very similar in appearance to Redpanda Connect (Benthos) which isn’t a bad thing at all. Would be good to elaborate on how error handling is done and what message delivery guarantees it comes with.
The most amusing thing I found about Go is that they built a presentation framework similar alongside the language. It's got some additional syntax on top of markdown but the documentation to use it can readily fit in an LLM's context window. I'd say it's good enough for many simple presentations.
Really nice project. What’s the reasoning behind the AGPL licensing. My understanding is that it will hurt adoption unless you’re planning to offer paid licensing options? Either way it’s a really nice project and I’m keen to try it out. I’ve found it tricky to get a WASM/WASI setup where I can at least my http requests (probably my own skill issue).
Author here.
Some context: Speakeasy lets you generate SDKs from OpenAPI 3.x specs and now every user that generates a TypeScript SDK gets a Model Context Protocol (MCP) server bundled with it. This is available to users on both free and paid tiers.
I've been the primary maintainer of TypeScript SDK codegen and since launching it early last year, I made a bet on Zod for defining models and tying static TypeScript types to runtime validation. During that time, LLM function calling became a widespread feature and we saw that lots of folks preferred defining function arguments using Zod schemas and having something like `zod-to-json-schema` convert them to JSON Schema.
Fast forward to MCP's release and we noticed that the TypeScript SDK also accepts Zod schemas for defining tool arguments. The "gap" between generating a TypeScript SDK and going further to generate an MCP server was so small for us that we jumped right on it.
In terms of other interesting bits, the server is built out into a single JavaScript file using Bun's bundler. We also use stricli (https://bloomberg.github.io/stricli/) for type-safe CLI argument parsing and code structuring. We're also looking at building MCP servers out into standalone binaries which would remove the pre-requisite for node.js and npx when installing them. It's also possible to register additional custom tools and resources on top of what we generate so you're not locked out just because it's generated code. The generated tool themselves are also regular ES modules. You can skip over most things and import them from the SDK and into your own MCP server if you're building one yourself.
This is spot on but the issue I called out in my post is that there’s nothing drawing devs to import the mapping. Like there’s the immediate convenience of passing a string literal to a field that’s a string union for instance. You’ve done a nice thing in your snippet and named the mapping and corresponding type the same but that’s also uncommon though I’m seeing it more nowadays. So as I see it it’s very possible to end up with a codebase that inconsistently uses the object mapping if that matters to you.
In principle you’ll still be able to use all of the features that existed before this flag but you’ll need to compile the code if targeting Node.js. I do think that this new flag is going to draw people away and we’ll probably see a bunch of tsconfig presets and boilerplate projects setting it to true.
If you’re using a bundler then your’re not to going benefit from it in the medium term. It’s possible this will unlock faster build times with them in the future.
One thing I find useful about enums is that they can be used as both types and values
Makes sense. You can emulate that behavior by having an object literal with const assertion AND a union type of the same name derived from the object literal.
Consider what happens in JavaScript when you declare a function as async. Now everything calling it is infected. Passing around runtime constructs like context in Go (AbortSignal in JS) or an allocator in Zig gives exactly the right level control back to the call and I love it. You can bail out of context propagation at any level of your program if that's your desire.
I’ve recently been tinkering with Rust and, while there have been countless articles praising its safety features, it’s the enums and match-expressions that are my favourite features. I want so much for Go to get these but I don’t know that it will. I get a little sad from the folks that so desperately want Go to be “Done” when there is a bunch of stuff that the language can add and be better for it.
Just trying this out and it seems amazing so far. Thanks for the tip!
Thanks! Really appreciate your comment :)
I've tried devcontainers in the past and the performance compared to my current setup was pretty bad. This was a few years ago when it was known that filesystem-heavy workloads on Docker for Mac were sub-optimal. I remember having to define several bind mounts which improved the overall performance. I do intend to revisit this solution next time I need to set up a dev environment but rest assured there was nothing substantially more complex about a VM versus devcontainers.
I work directly in my guest os and clone my projects and run them in there. There are some projects that are driven through docker-compose and that works nicely. The one caveat is that I had to install `apt install binfmt-support qemu-user-static` so that docker can run x86_64 images on my arm64 VM.
As others have mentioned, I’ve not had great performance with shared folders and the SSH extension in VS Code is so damn good. Over time, you forget it’s even running because you open recent projects and it remembers which were local (on host) and which are on the guest and SSH’s in automatically.
I could probably revise my use of Tailscale. My vague recollection is that I had networking issues when my laptop woke up and Tailscale didn’t have the same issues. Probably a debugging skill issue on my part.
Brilliant tip! I’m going to give it a shot tomorrow and update the post (with attribution).
Author here. Thank you for all the tips. I especially like the idea of using ssh from guest to host to enable pbcopy/pbpaste and open.
Now I know what all the WSL users experience seamlessly with their setups. Glad I have something that comes close.